package com.zero.logistics.controller;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zero.logistics.pojo.BaseData;
import com.zero.logistics.pojo.Customer;
import com.zero.logistics.pojo.CustomerExample;
import com.zero.logistics.pojo.MessageObject;
import com.zero.logistics.pojo.Role;
import com.zero.logistics.pojo.RoleExample;
import com.zero.logistics.pojo.User;
import com.zero.logistics.pojo.UserExample;
import com.zero.logistics.pojo.UserExample.Criteria;
import com.zero.logistics.service.CustomerService;
import com.zero.logistics.service.RoleService;
import com.zero.logistics.service.UserService;

/*
 *	@date:2020年3月31日 上午5:00:13
 *	@author:Zero
 *	@version:Future
 *	@description: 
 *
 */
@Controller
@RequestMapping("/admin")
public class AdminController {
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private CustomerService customerService;
	
	/**
	 * @function 认证失败跳转的方法
	 * @return
	 */
	@RequestMapping("/login")
	public String login(HttpServletRequest request, Model m) {
		//1.获取shiroLoginFailure对象，转成字符串
		String shiroLoginFailure = (String) request.getAttribute("shiroLoginFailure");
		System.out.println(shiroLoginFailure);  //打印调试
		//2.根据shiroLoginFailure来判断是否登录成功并会写响应数
		if (UnknownAccountException.class.getName().equals(shiroLoginFailure)) {
			m.addAttribute("errMsg", "用户不存在");
		} else if(IncorrectCredentialsException.class.getName().equals(shiroLoginFailure)){
			m.addAttribute("errMsg", "密码错误");
		}
		return "forward:/login.jsp";
	}

	@RequiresPermissions("admin:adminPage")
	@RequestMapping("/adminPage")
	public String adminPage() {
		return "adminPage";
	}
	
	/**
	 * @function 分页显示用户
	 * @param pageNum
	 * @param pageSize
	 * @param keywords
	 * @return
	 */
	@RequiresPermissions("admin:list")
	@RequestMapping("list")
	@ResponseBody  //返回json类型的数据
	public PageInfo<User> adminList(@RequestParam(defaultValue = "1")int pageNum,
			@RequestParam(defaultValue = "10")int pageSize,
			String keywords){
		
		PageHelper.startPage(pageNum, pageSize);
		UserExample example = new UserExample();
		
		// 定义搜索的逻辑（使用管理）
		if (StringUtils.isNotBlank(keywords)) {  //当前台传过来的关键字不等于空的时候
			//根据用户名查询
			Criteria criteria1 = example.createCriteria();
			criteria1.andUsernameLike("%" + keywords + "%");
			
			//根据真实姓名查询
			Criteria criteria2 = example.createCriteria();
			criteria2.andRealnameLike("%" + keywords + "%");
			example.or(criteria2);  //or关系
			
			//根据角色名称查询
			Criteria criteria3 = example.createCriteria();
			criteria3.andRolenameLike("%" + keywords + "%");
			example.or(criteria3);  //or关系
		}
		
		List<User> users = userService.selectByExample(example);
		PageInfo<User> pageInfo = new PageInfo<>(users);
		
		return pageInfo;
	}
	
	/**
	 * @function 删除用户
	 * @param userId
	 * @return
	 */
	@RequiresPermissions("admin:delete")
	@RequestMapping("/delete")
	@ResponseBody
	public MessageObject adminDelete(Long userId) {
		//1.删除之前判断被删除的用户是否为业务员，如果为业务员则需要判断该业务员是否还有关联的客户，如果有则不能删除
		User user = userService.selectByPrimaryKey(userId);
		if (user.getRoleId() == 3) {  //roleId为3的是业务员
			CustomerExample example = new CustomerExample();
			com.zero.logistics.pojo.CustomerExample.Criteria criteria = example.createCriteria();
			criteria.andUserIdEqualTo(userId);
			List<Customer> customers = customerService.selectByExample(example);
			if (customers.size() > 0) {
				return MessageObject.createMo(0, "被删除的用户下还关联有客户信息，不能删除");
			}
		}
		
		//2.根据userId删除数据
		int row = userService.deleteByPrimaryKey(userId);
		MessageObject mo = MessageObject.createMo(0, "删除数据失败，请联系技术人员");
		if (row == 1) {
			mo = MessageObject.createMo(1, "删除数据成功");
		}
		return mo;
	}
	
	/**
	 * @function 批量删除(以String类型接收前端传过来的参数)
	 * @param map
	 * @return
	 */
	@RequiresPermissions("admin:batchdel")
	@RequestMapping("/batchdel")
	@ResponseBody
	public MessageObject adminBatchdel(String userIds) {
		System.out.println(userIds);
		String[] userIdsArr = userIds.split(",");
		//1.删除之前判断被删除的用户是否为业务员，如果为业务员则需要判断该业务员是否还有关联的客户，如果有则不能删除
		for (String userId : userIdsArr) {
			User user = userService.selectByPrimaryKey(Long.parseLong(userId));
			if (user.getRoleId() == 3) {  //roleId为3的是业务员
				CustomerExample example = new CustomerExample();
				com.zero.logistics.pojo.CustomerExample.Criteria criteria = example.createCriteria();
				criteria.andUserIdEqualTo(Long.parseLong(userId));
				List<Customer> customers = customerService.selectByExample(example);
				if (customers.size() > 0) {
					return MessageObject.createMo(0, "被删除的用户下还关联有客户信息，不能删除");
				}
			}
		}
		
		//2.根据userId的字符串数组删除数据
		int rows = userService.deleteByIds(userIdsArr);
		MessageObject mo = MessageObject.createMo(0, "批量删除数据失败，请联系技术人员");
		if (rows != 0) {
			mo = MessageObject.createMo(1, "批量删除数据成功");
		}
		return mo;
	}
	
	/**
	 * @function 提供编辑页面(在新增用户和更新用户的时候都需要执行此方法)
	 * @param m
	 * @return
	 */
	@RequestMapping("/edit")
	public String adminEdit(Model m, Long userId) {	
		//1.当前端传过来的userId不为空的时候，就通过userId查询用户信息并共享数据
		if (userId != null) {
			User user = userService.selectByPrimaryKey(userId);
			System.out.println("需要更新的用户信息：" + user.getUserId());
			m.addAttribute("user", user);
		}
		//2.获取所有的角色信息并共享
		RoleExample example = new RoleExample();
		List<Role> roles = roleService.selectByExample(example);
		m.addAttribute("roles", roles);
		
		return "adminEdit";
	}
	
	/**
	 * @function 判断用户名是否存在
	 * @param username
	 * @return
	 */
	@ResponseBody
	@RequiresPermissions("admin:checkUsername")
	@RequestMapping("/checkUsername")
	public boolean adminCheckUsername(String username) {
		UserExample example = new UserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<User> users = userService.selectByExample(example);
		return users.size() == 0 ? true : false;
	}
	
	/**
	 * @function 新增用户
	 * @param user
	 * @return
	 */
	@RequiresPermissions("admin:insert")
	@RequestMapping("/insert")
	@ResponseBody
	public MessageObject adminInsert(User user) {
		// 1.用户密码加密(使用MD5加盐加3次散列算法)后注入到对象中
		String salt = UUID.randomUUID().toString().substring(0, 5);  //生成随机盐
		Md5Hash md5Hash = new Md5Hash(user.getPassword(), salt, 3);
		user.setSalt(salt);
		user.setPassword(md5Hash.toString());
		// 2.将创建日期注入到对象中
		user.setCreateDate(new Date());
		// 3.插入数据并返回结果
		int row = userService.insert(user);
		MessageObject mo = MessageObject.createMo(0, "添加数据失败，请联系技术人员");
		if (row == 1) {
			mo = MessageObject.createMo(1, "添加数据成功");
		}
		return mo;
	}
	
	@RequiresPermissions("admin:update")
	@RequestMapping("update")
	@ResponseBody
	public MessageObject adminUpdate(User user) {
		// 1.用户密码加密(使用MD5加盐加3次散列算法)后注入到对象中
		String salt = UUID.randomUUID().toString().substring(0,5);  //生成随机盐
		Md5Hash md5Hash = new Md5Hash(user.getPassword(), salt, 3);
		user.setPassword(md5Hash.toString());
		user.setSalt(salt);
		// 2.更新数据并返回结果(这里要用动态sql语句)
		int row = userService.updateByPrimaryKeySelective(user);
		MessageObject mo = MessageObject.createMo(0, "更新数据失败，请联系技术人员");
		if (row == 1) {
			mo = MessageObject.createMo(1, "更新数据成功");
		}
		return mo;
	}
	
	/*
	 * 测试commons-long.x.jar的一些功能
	 */
	public static void main(String[] args) {
		System.out.println(StringUtils.isBlank(""));
		System.out.println(StringUtils.isBlank(" "));
		System.out.println(StringUtils.isBlank(null));
		System.out.println(StringUtils.isBlank("abc"));
	}
}





